import {Common} from "@/utils/common.ts";

const format = "YYYY-MM-DD HH:mm:ss"

export interface ProcessFace {

    readonly id: string;

    readonly name: string;

    start(info?: string): void;

    finish(info?: string): void;

    process(info: string): void;

    error(info?: string): void;

    getEvent(): ProcessEvent[]
}

/**
 * 用来封装描述进程的类
 * 展示当前执行的任务
 */
class Process implements ProcessFace {

    readonly id: string;

    private observer: Observer[] = [];

    private event: ProcessEvent[] = [];

    private dead: boolean = null;

    readonly name: string;

    constructor(id: string, name?: string, observer?: Observer[]) {
        this.observer = observer;
        this.name = name ?? "匿名";
        this.id = id;
    }


    /**
     * 开始进程
     * @param info 进行提供的信息
     */
    start(info?: string) {
        if (this.dead != null) {
            return
        }
        this.dead = false
        let event = {
            type: "primary",
            timestamp: Common.formatTime(new Date(), format),
            id: this.id,
            info: info ?? `任务:${this.name} 启动`
        };
        this.event.push(event)
        this.observer?.forEach(observer => observer.start(event,this));
    }

    process(info: string) {
        if (this.dead) return
        let event = {
            type: "primary",
            timestamp: Common.formatTime(new Date(), format),
            id: this.id,
            info: info
        }
        this.event.push(event);
        this.observer?.forEach(observer => observer.process(event,this));
    }

    error(info?: string) {
        if (this.dead) return
        let event = {
            type: "error",
            timestamp: Common.formatTime(new Date(), format),
            id: this.id,
            info: info ?? `任务:${this.name} 出错`
        };
        this.event.push(event);
        this.observer?.forEach(observer => observer.error(event,this));
        this.dead = true;
    }

    finish(info?: string) {
        if (this.dead) return
        let event = {
            type: "success",
            timestamp: Common.formatTime(new Date(), format),
            id: this.id,
            info: info ?? `任务:${this.name} 完成`
        };
        this.event.push(event);
        this.observer?.forEach(observer => observer.finish(event,this));
        this.dead = true;
    }

    getEvent(): ProcessEvent[]{
        return this.event;
    }
}

export class ProcessManager {

    private static processes: Process[] = [];

    private static history: Process[] = [];

    private static error: Process[] = [];

    private static success: Process[] = [];

    private static signals: (() => void)[] = []

    private static observer: Observer = new class implements Observer {

        error(event: ProcessEvent,process:Process) {
            ProcessManager.processes = ProcessManager.processes.filter(item => item.id != event.id)
            ProcessManager.error.push(process)
            ProcessManager.notifyAll()
        }

        finish(event: ProcessEvent,process:Process) {
            ProcessManager.processes = ProcessManager.processes.filter(item => item.id != event.id)
            ProcessManager.history.push(process)
            ProcessManager.success.push(process)
            ProcessManager.notifyAll()
        }

        //@ts-ignore
        process(event: ProcessEvent,process:Process) {
            ProcessManager.notifyAll()
        }

        //@ts-ignore
        start(event: ProcessEvent,process:Process) {
            ProcessManager.processes.push(process)
            ProcessManager.notifyAll()
        }
    }


    /**
     * 添加进程
     * @param name
     * @param observer
     */
    static addProcess(name: string, observer?: Observer[]): ProcessFace {
        let uuid = Common.createUUID();
        return new Process(uuid, name, observer ? [ProcessManager.observer, ...observer] : [ProcessManager.observer]) as ProcessFace;
    }

    static getProcesses(): Process[] {
        return ProcessManager.processes;
    }

    static getHistory(): Process[] {
        return ProcessManager.history;
    }

    static getError(): Process[] {
        return ProcessManager.error;
    }

    static getSuccess(): Process[] {
        return ProcessManager.success;
    }

    static signal(callback: () => void) {
        this.signals.push(callback)
    }

    private static notifyAll() {
        for (let signal of this.signals) {
            signal()
        }
    }

    /**
     * 根据processId获取对象
     */
    static getProcess(id: string): ProcessFace {
        let list = [...ProcessManager.processes, ...ProcessManager.history, ...ProcessManager.error]
        return list.find(process => process.id === id) as ProcessFace;
    }
}

/**
 * 监听器
 */
interface Observer {
    start(event: ProcessEvent,process:Process);

    process(event: ProcessEvent,process:Process);

    error(event: ProcessEvent,process:Process);

    finish(event: ProcessEvent,process:Process);
}

export interface ProcessEvent {

    /**
     * 进程信息
     */
    readonly info: string;

    readonly id: string;

    readonly type: string;

    readonly timestamp: string;
}